package com.wang.friend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wang.friend.domain.question.Question;

import com.wang.friend.domain.question.dto.QuestionQueryDTO;
import com.wang.friend.domain.question.es.QuestionES;
import com.wang.friend.domain.question.vo.QuestionDetailVO;
import com.wang.friend.domain.question.vo.QuestionVO;
import com.wang.friend.elasticsearch.QuestionRepository;
import com.wang.friend.manager.QuestionCacheManager;
import com.wang.friend.mapper.question.QuestionMapper;
import com.wang.friend.service.IQuestionService;
import com.wang.common.core.domain.TableDataInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class QuestionServiceImpl implements IQuestionService {

    @Autowired
    private QuestionRepository questionRepository;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private QuestionCacheManager questionCacheManager;

    @Override
    public TableDataInfo list(QuestionQueryDTO questionQueryDTO) {
        //1.首先查询es中数据的个数,如果<=0,则刷新es
        if (questionRepository.count() <= 0){
            refreshQuestion();
        }

        //2.使用SpringFramework设置分页信息
        Sort sort = Sort.by(Sort.Direction.DESC,"createTime");//设置排序规则,根据创建时间进行排序
        Pageable pageRequest = PageRequest.of(questionQueryDTO.getPageNum()-1, questionQueryDTO.getPageSize(),sort);

        Page<QuestionES> questionESPage;//SpringFramework中的分页类

        //关键字
        String keyword = questionQueryDTO.getKeyword();
        //难度
        Integer difficulty = questionQueryDTO.getDifficulty();

        //3.从ES中查询相关信息
        if (difficulty == null && StrUtil.isEmpty(keyword)){
            //难度和关键字都为空 --> 搜索到所有数据
            questionESPage = questionRepository.findAll(pageRequest);//使用上面在springFramework中设置的额分页信息
        }else if (difficulty != null && StrUtil.isEmpty(keyword)){
            //难度不为空,关键字为空 --> 根据难度搜索数据
            questionESPage = questionRepository.findQuestionByDifficulty(difficulty,pageRequest);
        }else if (difficulty == null && StrUtil.isNotEmpty(keyword)){
            //难度为空,关键字不为空 --> 根据关键字搜索数据
            questionESPage = questionRepository.findByTitleOrContent(keyword,keyword,pageRequest);
        }else {
            //难度和关键字都不为空 --> 根据难度和关键字搜索数据
            questionESPage = questionRepository.findByTitleOrContentAndDifficulty(keyword,keyword,difficulty,pageRequest);
        }

        //返回QuestionVO结果
        long total = questionESPage.getTotalElements(); //获取到整个数据集的个数

        if (total <= 0){
            return TableDataInfo.empty();
        }

        //从分页类中获取当前分页的内容
        List<QuestionES> questionESList = questionESPage.getContent();

        List<QuestionVO> questionVOList = BeanUtil.copyToList(questionESList, QuestionVO.class);

        return TableDataInfo.success(questionVOList,total);
    }

    @Override
    public QuestionDetailVO detail(Long questionId) {
        //1.首先从es中查询
        QuestionES questionES = questionRepository.findById(questionId).orElse(null);

        QuestionDetailVO questionDetailVO = new QuestionDetailVO();

        //如果存在,直接返回
        if (questionES != null){
            BeanUtil.copyProperties(questionES,questionDetailVO);
            return questionDetailVO;
        }

        //2.如果不存在,去数据库中查询
        Question question = questionMapper.selectById(questionId);

        //如果数据库中也不存在,直接返回null
        if (question == null) return null;

        //3.如果数据库中存在,则刷新es
        refreshQuestion();

        //返回结果
        BeanUtil.copyProperties(questionES,questionDetailVO);
        return questionDetailVO;
    }

    @Override
    public String preQuestion(Long questionId) {

        //1.从缓存中获取题目id列表的大小
        Long listSize = questionCacheManager.getListSize();

        //如果为null或者是小于等于0,刷新缓存
        if (listSize == null || listSize <= 0){
            questionCacheManager.refreshCache();
        }

        //找到index在当前题目前一个的 题目id 并返回
        return questionCacheManager.preQuestion(questionId).toString();
    }

    @Override
    public String nextQuestion(Long questionId) {
        //1.从缓存中获取题目id列表的大小
        Long listSize = questionCacheManager.getListSize();
        //如果为null或者是小于等于0,刷新缓存
        if (listSize == null || listSize <= 0){
            questionCacheManager.refreshCache();
        }
        //找到index在当前题目后一个的 题目id 并返回
        return questionCacheManager.nextQuestion(questionId).toString();
    }

    /**
     * 从数据库中查询问题数据,并刷新es
     */
    private void refreshQuestion(){

        //从数据库中查询所有的数据
        List<Question> questionList = questionMapper.selectList(new LambdaQueryWrapper<>());

        //如果数据库中也没有数据,直接返回
        if (CollectionUtil.isEmpty(questionList)){
            return;
        }

        //拿到数据之后刷新es
        List<QuestionES> questionESList = BeanUtil.copyToList(questionList,QuestionES.class);

        questionRepository.saveAll(questionESList);
    }
}
